/*
 * main.c
 *
 *  Created on: 19 août 2011
 *      Author: cedric
 */

#include <stdio.h>
#include <stdlib.h>
#include "MyResampler.h"
#include "MyReferenceResampler.h"
//#include "sndfile.h"
#include <time.h>
#include <string.h>
#include <assert.h>

//static SNDFILE* out_file;

static sample_t results[100];
static int results_index;
static sample_t reference_results[100];
static int reference_results_index;

void resampler_test_callback(sample_t* s, buffer_size_t size) {
	results[results_index] = s[0];
	results_index++;
	//printf("%.4f \n", s[0]);
}

void resampler_reference_test_callback(sample_t s) {
	reference_results[reference_results_index] = s;
	reference_results_index++;
	printf("%.4f \n", s);
}

void test_reference() {
	int taps = 12;
	int in_rate = 2;
	int out_rate = 5;

	MyResampler my_rs = my_resampler_new(taps, in_rate, out_rate, 1,
			WINDOW_NONE, &resampler_test_callback);
	my_resampler_set_clipping(my_rs, false);
	MyReferenceResampler my_ref_rs = my_reference_resampler_new(taps, 2, in_rate,
			out_rate, WINDOW_NONE, &resampler_reference_test_callback);

	//create some input data
	static const sample_t in_buffer[40] = {
			1.0, 1.0,
			2.0, 2.0,
			3.0, 3.0,
			4.0, 4.0,
			5.0, 5.0,
			6.0, 6.0,
			7.0, 7.0,
			8.0, 8.0,
			9.0, 9.0,
			10.0,10.0,
			11.0, 11.0,
			12.0, 12.0,
			13.0, 13.0,
			14.0, 14.0,
			15.0, 15.0,
			0.0, 0.0,
			0.0, 0.0,
			0.0, 0.0,
			0.0, 0.0,
			0.0, 0.0,
	};

	memset(results, 0, 100);
	results_index = 0;
	memset(reference_results, 0, 100);
	reference_results_index = 0;

	//process data through both resamplers
	int i;
	sample_t s[1];
	sample_t* ss;
	for (i = 0; i < 10; i++) {
		ss = &in_buffer[i*2];
		my_reference_resampler_process_sample(my_ref_rs, ss);
		s[0] = in_buffer[i];
		my_resampler_process_sample(my_rs, s, 1);
	}

	my_resampler_destroy(my_rs);
	my_reference_resampler_destroy(my_ref_rs);

	/*
	 * Now, check the results
	 */

	//assert(results_index == reference_results_index);
	puts("\treference\tresult");
	int min_index;
	min_index = min(results_index,reference_results_index);
	for (i = 0; i <= min_index; i++) {
		if (reference_results[i] != results[i]) {
			printf(">");
		}
		printf("\t%.6f\t\t%.6f\n", reference_results[i], results[i]);
	}
	if (results_index > reference_results_index) {
		for (i = reference_results_index + 1; i <= results_index; i++) {
			printf("\t\t\t%.6f\n", results[i]);
		}
	} else if (reference_results_index > results_index) {
		for (i = results_index + 1; i <= reference_results_index; i++) {
			printf("\t%.6f\t\t\n", reference_results[i]);
		}
	}

	for (i = 0; i <= results_index; i++) {
		//assert(reference_results[i]==results[i]);
	}

}
/*
void resampler_callback(sample_t* s, buffer_size_t size) {

	if (sf_write_double(out_file, s, size) == 0) {
		//puts("0 written");
	}
	//printf("%.4f \n", s);
}
*/

int main(void) {

	/*
	 * Start by testing non-regression
	 */

	test_reference();

	/*
	 * Now, serious stuff: let's resample some real music
	 */

#define NTAPS 1280*16
#define input_rate 44100
#define output_rate 192000
#define read_count 44100 * 10

	/*SF_INFO sfi_in;
	sfi_in.channels = 1;
	sfi_in.samplerate = input_rate;
	sfi_in.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;

	SNDFILE* in_file = sf_open("/home/cedric/temp/input.wav", SFM_READ,
			&sfi_in);

	if (in_file == NULL) {
		puts(sf_strerror(in_file));
	}

	SF_INFO sfi_out;
	sfi_out.samplerate = output_rate;
	sfi_out.channels = 1;
	sfi_out.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
	out_file = sf_open("/home/cedric/temp/output.wav", SFM_WRITE, &sfi_out);

	if (out_file == NULL) {
		puts(sf_strerror(out_file));
	}

	double *in_buffer = malloc(read_count * sizeof(double));

	sf_count_t res = sf_read_double(in_file, in_buffer, read_count);

	//init resampler
	MyResampler my_rs = my_resampler_new(NTAPS, input_rate, output_rate, 1024,
			WINDOW_BLACKMAN, &resampler_callback);

	//process data through resampler
	my_resampler_process_sample(my_rs, in_buffer, res);
	my_resampler_destroy(my_rs);

	printf("total time: %.2f seconds\n", (double) clock() / 1000000);

	sf_close(in_file);
	sf_close(out_file);
	*/

	return 0;
}
